import { http } from "@/utils/http";
import type { ApiResponse } from "../../user";
import { ensureArray, normalisePagination, toNumber } from "@/api/_helpers";

const TEMPLATE_BASE = "/system/notify/template";

export interface TemplateChannel {
  enabled: boolean;
  route?: string;
  [key: string]: any;
}

export type TemplateChannelMap = Record<string, TemplateChannel>;

export interface TemplateItem {
  id: number;
  name: string;
  title: string;
  content: string;
  type: string;
  category?: string;
  status: number;
  channels: TemplateChannelMap;
  description?: string;
  remark?: string;
  create_time?: string;
  update_time?: string;
  [key: string]: any;
}

export interface TemplateListParams {
  page?: number;
  page_size?: number;
  keyword?: string;
  category?: string;
  status?: number | string;
  channel?: string;
  type?: string;
}

export interface TemplateListResult {
  list: TemplateItem[];
  categories: string[];
  channels: string[];
  total: number;
  pageSize: number;
  currentPage: number;
  raw?: any;
}

export interface TemplatePayload {
  name: string;
  title: string;
  content: string;
  type: string;
  category?: string;
  status?: number;
  channels?: TemplateChannelMap;
  description?: string | null;
  remark?: string | null;
}

const parseChannels = (value: unknown): TemplateChannelMap => {
  if (!value) return {};

  if (typeof value === "string") {
    try {
      const parsed = JSON.parse(value) as Record<string, any>;
      return parseChannels(parsed);
    } catch {
      return {};
    }
  }

  if (Array.isArray(value)) {
    return value.reduce<TemplateChannelMap>((acc, item) => {
      if (!item) return acc;
      const key = item?.channel ?? item?.name ?? item?.type;
      if (!key) return acc;
      acc[String(key)] = {
        enabled: Boolean(item.enabled ?? item.status ?? item.active ?? true),
        route: item.route ?? item.path ?? ""
      };
      return acc;
    }, {});
  }

  if (typeof value === "object") {
    return Object.entries(
      value as Record<string, any>
    ).reduce<TemplateChannelMap>((acc, [channel, config]) => {
      acc[channel] = {
        enabled: Boolean(
          (config as any)?.enabled ??
            (config as any)?.status ??
            (config as any)?.active ??
            true
        ),
        route: (config as any)?.route ?? (config as any)?.path ?? ""
      };
      return acc;
    }, {});
  }

  return {};
};

const mapTemplate = (item: Record<string, any>): TemplateItem => {
  return {
    id: toNumber(item.id, 0),
    name: item.name ?? "",
    title: item.title ?? "",
    content: item.content ?? "",
    type: item.type ?? item.code ?? "",
    category: item.category ?? "",
    status: toNumber(item.status ?? item.enable ?? 1, 1),
    channels: parseChannels(item.channels ?? item.channel_config ?? {}),
    description: item.description ?? item.desc ?? "",
    remark: item.remark ?? "",
    create_time: item.create_time ?? item.created_at ?? "",
    update_time: item.update_time ?? item.updated_at ?? ""
  };
};

const fetchList = async (
  params: TemplateListParams = {}
): Promise<TemplateListResult> => {
  const page = toNumber(params.page, 1);
  const pageSize = toNumber(params.page_size, 10);
  const res = await http.request<ApiResponse<any>>("get", TEMPLATE_BASE, {
    params: {
      ...params,
      page,
      page_size: pageSize
    }
  });

  const payload = (res?.data as Record<string, any>) ?? {};
  const listSource =
    payload.list ?? payload.data ?? payload.records ?? payload.items ?? [];
  const list = ensureArray<Record<string, any>>(listSource).map(mapTemplate);

  const pagination = normalisePagination(
    payload.pagination ?? payload,
    page,
    pageSize,
    list.length
  );

  const categories = ensureArray<string>(payload.categories ?? []);
  const channels = ensureArray<string>(
    payload.channels ?? payload.channel ?? []
  );

  return {
    list,
    categories,
    channels,
    total: pagination.total,
    pageSize: pagination.pageSize,
    currentPage: pagination.currentPage,
    raw: payload
  };
};

const fetchDetail = async (id: number): Promise<TemplateItem> => {
  const res = await http.request<ApiResponse<any>>(
    "get",
    `${TEMPLATE_BASE}/${id}`
  );
  const payload = (res?.data as Record<string, any>) ?? {};
  if (payload?.id !== undefined) {
    return mapTemplate(payload);
  }
  return mapTemplate(payload ?? {});
};

const create = async (payload: TemplatePayload): Promise<TemplateItem> => {
  const res = await http.request<ApiResponse<any>>("post", TEMPLATE_BASE, {
    data: payload
  });
  const data = (res?.data as Record<string, any>) ?? {};
  return mapTemplate(data);
};

const update = async (
  id: number,
  payload: Partial<TemplatePayload>
): Promise<TemplateItem> => {
  const res = await http.request<ApiResponse<any>>(
    "put",
    `${TEMPLATE_BASE}/${id}`,
    {
      data: payload
    }
  );
  const data = (res?.data as Record<string, any>) ?? {};
  return mapTemplate(data);
};

const remove = async (id: number): Promise<boolean> => {
  const res = await http.request<ApiResponse<any>>(
    "delete",
    `${TEMPLATE_BASE}/${id}`
  );
  if (typeof res?.data === "boolean") return res.data;
  if (res?.success !== undefined) return Boolean(res.success);
  return true;
};

const toggleStatus = async (
  id: number,
  status: number
): Promise<TemplateItem> => {
  const res = await http.request<ApiResponse<any>>(
    "patch",
    `${TEMPLATE_BASE}/${id}/status`,
    {
      data: { status }
    }
  );
  const data = (res?.data as Record<string, any>) ?? {};
  return mapTemplate(data);
};

export default {
  fetchList,
  fetchDetail,
  create,
  update,
  remove,
  toggleStatus
};
